package test.fairway;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.amazonaws.auth.policy.Action;
import com.amazonaws.auth.policy.Policy;
import com.amazonaws.auth.policy.Resource;
import com.amazonaws.auth.policy.Statement;
import com.amazonaws.auth.policy.Statement.Effect;
import com.amazonaws.auth.policy.actions.S3Actions;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.Credentials;
import com.amazonaws.services.securitytoken.model.GetFederationTokenRequest;
import com.amazonaws.services.securitytoken.model.GetFederationTokenResult;

public class LocalS3CrentialGetter implements IS3CredentialGetter {

	@Override
	public S3SessionCredential getS3Crential(String user, String bucket, int duration, List<S3Permission> permissions) {
		AWSSecurityTokenServiceClient stsClient = new AWSSecurityTokenServiceClient(new ProfileCredentialsProvider());

		GetFederationTokenRequest getFederationTokenRequest = new GetFederationTokenRequest();
		getFederationTokenRequest.setDurationSeconds(duration);
		getFederationTokenRequest.setName(user);

		ArrayList<Statement> statements = new ArrayList<Statement>();
		for (S3Permission permission : permissions) {
			Action action = null;
			List<Resource> resources = new ArrayList<Resource>();

			switch (permission.getOperation()) {
			case DownloadObject:
				action = S3Actions.GetObject;
				break;
			case UploadObject:
				action = S3Actions.PutObject;
				break;
			case DeleteObject:
				action = S3Actions.DeleteObject;
				break;
			case ListObject:
				action = S3Actions.ListObjects;
				break;
			}

			if (permission.getOperation() == S3Operation.ListObject) {
				resources.add(new Resource("arn:aws:s3:::" + bucket));
			} else {
				for (String resource : permission.getObjectKeys()) {
					resources.add(new Resource("arn:aws:s3:::" + bucket + "/" + resource));
				}
			}
			Statement statement = new Statement(Effect.Allow).withActions(action);
			statement.setResources(resources);
			statements.add(statement);
		}

		Policy policy = new Policy(UUID.randomUUID().toString(), statements);
		System.out.println(policy.toJson());
		getFederationTokenRequest.setPolicy(policy.toJson());
		GetFederationTokenResult federationTokenResult = stsClient.getFederationToken(getFederationTokenRequest);
		Credentials sessionCredentials = federationTokenResult.getCredentials();

		return new S3SessionCredential(sessionCredentials.getAccessKeyId(), sessionCredentials.getSecretAccessKey(),
				sessionCredentials.getSessionToken(), duration);
	}

}
